home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / utils / inter37c.arj / 86BUGS.LST next >
File List  |  1993-07-22  |  14KB  |  382 lines

  1. Last Change 7/17/93.  Please send updates directly to Harald.
  2.  
  3.  
  4. 86BUGS.LST   revision 1.0
  5. By Harald Feldmann (harald.feldmann@almac.co.uk), mail address:
  6. Hamarsoft, p.o. box 91, 6114 ZH  Susteren, The Netherlands.
  7. (Please retain my name and address in the document)
  8.  
  9. This file lists undocumented and buggy instructions of the Intel 80x86
  10. family of processors. Some of the information was obtained from the book
  11. "Programmer's technical reference, the processor and coprocessor; by
  12. Robert L. Hummel; Ziff davis press. ISBN 1-56276-016-5 Which is highly
  13. recommended. Note that Intel does not support the special features and
  14. may decide to drop opcode variants and instructions in future products.
  15.  
  16. All mentioned trademarks and/or tradenames are owned by the respective
  17. owners and are acknowledged.
  18.  
  19. Undocumented instructions and undocumented features of Intel and IIT
  20. processors:
  21.  
  22. AAD:        OPCODE: d5,0a     OPCODE VARIANT
  23.  
  24.         This instruction regularly performs the following action:
  25.         - unpacked BCD in AX      example (AX = 0104h)
  26.         - AL = AH * 10d + AL          (AL = 0eh )
  27.         - AH = 00              (AH = 00h )
  28.  
  29.         The normal opcode decodes as follows: d5,0a
  30.         The instruction itself is an instruction plus operand. By
  31.         replacing the second byte with any number in the range 00 -
  32.         ff we can build our own instruction AAD for various number
  33.         systems in those ranges. For example by coding d5,10 we
  34.         achieve an instruction that performs: AL = AH * 16d + AL.
  35.  
  36. AAM:        OPCODE: d4,0a     OPCODE VARIANT
  37.  
  38.         This instruction regularly performs the following action:
  39.         - binary number in AL
  40.         - AH = AL / 10d
  41.         - AL = AL MOD 10d
  42.  
  43.         Thus creating an unpacked BCD in AX.
  44.         The normal opcode decodes as follows: d4,0a
  45.         The instruction itself is an instruction plus operand. By
  46.         replacing the second byte with any number in the range 00 -
  47.         ff we can build our own instruction AAM for various number
  48.         systems in that range. For example by coding d4,07 we
  49.         achieve an instruction that performs: AH = AL / 07d, AL = AL
  50.         MOD 07d
  51.  
  52.         The AAD and AAM opcode variants have been found in Future
  53.         Domain SCSI controller ROMS.
  54.  
  55.  
  56. LOADALL:    OPCODE: 0f,05 (i80286) & 0f,07 (i80386 & i80486)
  57.         UNDOCUMENTED
  58.  
  59.         Load _ALL_ processor registers. Does exactly as the name
  60.         suggests, separate versions for i80286 and i80386 exist. The
  61.         i80286 LOADALL instruction reads a block of 102 bytes into
  62.         the chip, starting at address 000800 hex. The i80286 LOADALL
  63.         takes 195 clocks to execute.
  64.         The sequence is as follows (Hex address, Bytes, Register):
  65.  
  66.         0800: 6 N/A
  67.         0806: 2 MSW (Machine Status Word)
  68.         0808: 14 N/A
  69.         0816: 2 TR (Task Register)
  70.         0818: 2 FLAGS (Flags)
  71.         081a: 2 IP (Instruction Pointer)
  72.         081c: 2 LDT (Local Descriptor Table)
  73.         081e: 2 DS (Data Segment)
  74.         0820: 2 SS (Stack Segment)
  75.         0822: 2 CS (Code Segment)
  76.         0824: 2 ES (Extra Segment)
  77.         0826: 2 DI (Destination Index)
  78.         0828: 2 SI (Source Index)
  79.         082a: 2 BP (Base Pointer)
  80.         082c: 2 SP (Stack Pointer)
  81.         082e: 2 BX (BX register)
  82.         0830: 2 DX (DX register)
  83.         0832: 2 CX (CX register)
  84.         0834: 2 AX (AX register)
  85.         0836: 6 ES cache (ES descriptor _cache_)
  86.         083c: 6 CS cache (CS descriptor _cache_)
  87.         0842: 6 SS cache (SS descriptor _cache_)
  88.         0848: 6 DS cache (DS descriptor _cache_)
  89.         084e: 6 GDTR (Global Descriptor Table)
  90.         0854: 6 LDT cache (Local Descriptor_cache_)
  91.         085a: 6 IDTR (Interrupt Descriptor table)
  92.         0860: 6 TSS cache (Task State Segment _cache_)
  93.  
  94.         Descriptor cache entries are internal copies of the
  95.         original registers (the LDT cache is normally a copy of the
  96.         last regularly _loaded_ LDT). Note that after executing
  97.         LOADALL, the chip will use the _cache_ registers without
  98.         re-checking the caches against the regular registers. That
  99.         means that cache and register do not have to be the same.
  100.         Caches are updated when the original register is loaded
  101.         again. Both will then contain the same value.
  102.  
  103.         Descriptor caches layout:
  104.         3 bytes       24 bit physical address of segment
  105.         1 byte       access rights byte, mapped as access right
  106.                byte in a regular descriptor. The present
  107.                bit now represents a valid bit. If this bit
  108.                is cleared (zero) the segment is invalid and
  109.                accessing it will trigger exception 0dh. The
  110.                DPL (Descriptor Privilege Level) fields of
  111.                the CS and SS descriptor caches determine
  112.                the CPL (Current Privilege Level).
  113.         2 bytes       16 bit segment limit.
  114.         This layout is the same for the GDTR and IDTR registers,
  115.         except that the access rights byte must be zero.
  116.  
  117.  
  118.         i80386 LOADALL:
  119.         The i80386 variant loads 204 (dec) bytes from the address at
  120.         ES:EDI and resumes execution in the specified state.
  121.         No timing information available.
  122.  
  123.         relative offset: Bytes:   Registers:
  124.         0000:         4          CR0
  125.         0004:         4          EFLAGS
  126.         0008:         4          EIP
  127.         000c:         4          EDI
  128.         0010:         4          ESI
  129.         0014:         4          EBP
  130.         0018:         4          ESP
  131.         001c:         4          EBX
  132.         0020:         4          EDX
  133.         0024:         4          ECX
  134.         0028:         4          EAX
  135.         002c:         4          DR6
  136.         0030:         4          DR7
  137.         0034:         4          TR
  138.         0038:         4          LDT
  139.         003c:         4          GS (zero extended)
  140.         0040:         4          FS (zero extended)
  141.         0044:         4          DS (zero extended)
  142.         0048:         4          SS (zero extended)
  143.         004c:         4          CS (zero extended)
  144.         0050:         4          ES (zero extended)
  145.         0054:        12          TSS descriptor cache
  146.         0060:        12          IDT descriptor cache
  147.         006c:        12          GDT descriptor cache
  148.         0078:        12          LDT descriptor cache
  149.         0084:        12          GS descriptor cache
  150.         0090:        12          FS descriptor cache
  151.         009c:        12          DS descriptor cache
  152.         00a8:        12          SS descriptor cache
  153.         00b4:        12          CS descriptor cache
  154.         00c0:        12          ES descriptor cache
  155.  
  156.         Descriptor caches layout:
  157.         1 byte       zero
  158.         1 byte       access rights byte, same as i80286
  159.         2 bytes       zero
  160.         4 bytes       32 bit physical base address of segment
  161.         4 bytes       32 bit segment limit
  162.  
  163.  
  164. UNKNOWN:    OPCODE: 0f,04     UNDOCUMENTED
  165.  
  166.         This instruction is likely to be an alias for the LOADALL on
  167.         the i80286. It is not documented and is even marked as
  168.         unused in the 'Programmer's technical reference'. Still it
  169.         executes on the i80286. >> info wanted <<
  170.  
  171.  
  172. SETALC:     OPCODE: d6          UNDOCUMENTED
  173.  
  174.         This instruction copies the Carry Flag to the AL register.
  175.         In case of a CY, AL becomes ffh. When the Carry Flag is
  176.         cleared, AL becomes 00.
  177.  
  178.  
  179. Floating Point special instructions:
  180.  
  181. FMUL4X4:    OPCODE: db,f1     IIT ONLY
  182.  
  183.         This instruction is available only on the IIT (Integrated
  184.         Information Technology Inc.) math processors.
  185.         Takes 242 clocks.
  186.         The instruction performs a 4x4 matrix multiply in one
  187.         instruction using four banks of 8 floating point registers.
  188.         The operands must be loaded to a specific bank in a specific
  189.         order. The equation solved can be represented by:
  190.  
  191.         Xn = (A00 * Xo) + (A01 * Xo) + (A02 * Xo) + (A03 * Xo)
  192.         Yn = (A10 * Yo) + (A11 * Yo) + (A12 * Yo) + (A13 * Yo)
  193.         Zn = (A20 * Zo) + (A21 * Zo) + (A22 * Zo) + (A23 * Zo)
  194.         Vn = (A30 * Vo) + (A31 * Vo) + (A32 * Vo) + (A33 * Vo)
  195.  
  196.         Where Xo stands for the original X value and Xn for the
  197.         result. Operands must be loaded to the following registers
  198.         in the specified banks in the specified order.
  199.  
  200.            Before FMUL4X4         After FMUL4X4
  201.  
  202.                 bank           bank
  203.         Register:    0    1      2         0
  204.  
  205.         ST(0)  Xo   A33  A31        Xn
  206.         ST(1)  Yo   A23  A21        Yn
  207.         ST(2)  Zo   A13  A11        Zn
  208.         ST(3)  Vo   A03  A01        Vn
  209.         ST(4)        A32  A30         ?
  210.         ST(5)        A22  A20         ?
  211.         ST(6)        A12  A10         ?
  212.         ST(7)        A02  A00         ?
  213.  
  214.  
  215.  
  216.         All four banks can be selected by using the bankswitching
  217.         instructions, but only bank 0, 1 and 2 make sense since bank
  218.         3 is an internal scratchpad. The separate banks can contain
  219.         8 floating points and may be re-used with normal
  220.         instructions. Each bank acts like an independent i80287,
  221.         except when bankswitched inbetween, in those cases where the
  222.         initial status is not maintained;
  223.  
  224.         Pseudo- multichip operation can be performed in each bank
  225.         and even in multiple banks at the same time (although only
  226.         one instruction will operate on one register at any given
  227.         time), provided that the active register and top register
  228.         are not changed after switching from bank to bank.
  229.  
  230.  
  231.         EXAMPLE:
  232.         FINIT                 ; reset control word
  233.         FSBP1                 ; select bank 1
  234.         FLD DWORD PTR es:[si]         ; first original
  235.         FLD DWORD PTR es:[si+4]      ; second original
  236.         FLD DWORD PTR es:[si+8]      ; third original
  237.         FSTCW WORD PTR [bx]         ; save FPU control status
  238.         FSBP2                 ; NOTE ! you will see three
  239.                            active registers in this
  240.                            bank when using a
  241.                            debugger
  242.         FINIT                 ; nothing visible
  243.         FLD DWORD PTR [si]         ; new value
  244.         FLD DWORD PTR [si+4]         ; second new value
  245.         FADD ST,ST(1)             ; two values visible
  246.         FSTP DWORD PTR [si+8]         ; one value visible
  247.         FSBP1                 ; one original visible
  248.         FLDCW WORD PTR [bx]         ; restore FPU status to the
  249.                            one active in bank 1,
  250.                            causing original three
  251.                            values to be visible
  252.                            again in correct
  253.                            sequence
  254.  
  255.         ... simply continue with what you wanted to do with
  256.         those numbers from es:[si], they are still there.
  257.  
  258.         FLD DWORD PTR [si+8]         ; for instance...
  259.  
  260.  
  261.         This feature of the IIT chips can be used to perform complex
  262.         operations in registers with many components remaining the
  263.         same for a large dataset, only saving intermediary results
  264.         to ONE memory location, bankswitching to the next series of
  265.         operands, loading that ONE operand and continuing the
  266.         calculation with the next set of operands already in that
  267.         bank. This does require another read into the new bank but
  268.         may save time and memoryspace compared to memory based
  269.         operands or multiple pass algorithms with multiple arrays of
  270.         intermediary results.
  271.  
  272.  
  273.  
  274. BANKSWITCH INSTRUCTIONS:
  275.  
  276. FSBP0:        OPCODE: db,e8     IIT ONLY
  277.         Selects the original bank. (default) (6 clocks)
  278.  
  279.  
  280. FSBP1:        OPCODE: db,eb     IIT ONLY
  281.  
  282.         Selects bank 1 from FMUL4X4 instruction diagram (6 clocks)
  283.  
  284.  
  285. FSBP2:        OPCODE: db,ea     IIT ONLY
  286.  
  287.         Selects bank 2 from FMUL4X4 instruction diagram (6 clocks)
  288.  
  289. FSBP3:        OPCODE: db,e9     IIT ONLY     UNDOCUMENTED
  290.         Selects the scratchpad bank3 used by the FMUL4X4 internally.
  291.         Not very useful but funny to look at... How-to: load
  292.         any value into bank 0,1 or 2 until you have a full 8
  293.         registers, then execute this bankswitch. Using a
  294.         debugger like CodeView you are now able to inspect the
  295.         bank3 registers. (most likely to take 6 clocks)
  296.  
  297.  
  298.  
  299. TRIGONIOMETRIC FUNCTIONS:
  300.  
  301.         Apparently the IIT 2c87 recognises and executes some
  302.         i80387 trigoniometric functions. UNDOCUMENTED
  303.         FSIN (sine) and FCOS (cosine) have been tested and function
  304.         according to the Intel 80387 specifications. FSINCOS
  305.         (available on the Intel 80287XL, 80387 and up) does not
  306.         work.
  307.  
  308. FSIN:        OPCODE: d9,fe     IIT 2c87+ (also Intel 80387+) UNDOCUMENTED
  309.         Calculates the sine of the input in radians in ST(0). After
  310.         calculation, ST(0) contains the sine. Takes approximately
  311.         120 clocks.
  312.  
  313. FCOS:        OPCODE: d9,ff     IIT 2c87+ (also Intel 80387+) UNDOCUMENTED
  314.         Calculates the cosine of the input in radians in ST(0).
  315.         After calculation, ST(0) contains the cosine. Takes
  316.         approximately 120 clocks.
  317.  
  318.  
  319. ... CUT HERE FOR FIRST REVISION, next part is to be revised ...
  320.  
  321.  
  322.  
  323. Instructions by mnemonic mnemonic:
  324. opcode: processor:  remark & remedy:
  325.  
  326. AAA           i80286 & i80386 & i80486
  327.  
  328. CMPS            i80286
  329. CMPXCHG         i80486
  330. FINIT
  331. FSTSW
  332. FSTCW
  333.  
  334.  
  335. INS            i80286 &
  336.             i80386 &
  337.             i80486
  338.  
  339. INVD            i80486
  340.  
  341.  
  342.  
  343. MOV to SS     n/a    early 8088  Some early 8088 would not properly
  344.                     disable interrupts after a move to
  345.                     the SS register. Workaround would
  346.                     be to explicitly clear the
  347.                     interrupts, update SS and SP and
  348.                     then re-enable the interrupts.
  349.                     Typically this would occur in a
  350.                     situation where one would relocate
  351.                     a stack in memory, more than 64Kb
  352.                     from the original one, updating
  353.                     both SS and SP like in:
  354.                       MOV SS,AX  ; would disable
  355.                            interrupts
  356.                            automatically during
  357.                            this and next
  358.                            instruction.
  359.                       MOV SP,DX  ; interrupts disabled
  360.                       ...     ; interrupts enabled.
  361.  
  362.  
  363. multiple prefixes
  364. with REPx        8088 & 8086 They would not properly restart at
  365.                     the first prefix byte after an
  366.                     interrupt. when more than one
  367.                     prefix is used. e.g. LOCK REP MOVSW
  368.                     CS:[bx]. A workaround is to test
  369.                     after the instruction for CX==0,
  370.                     here: LOCK REP MOVSW CS:[BX] OR
  371.                     CX,CX JNZ here because of the CS
  372.                     override, the REP and LOCK prefixes
  373.                     would not be recognised to be part
  374.                     of the instruction and the REP MOVSW
  375.                     would be aborted. This also seems to
  376.                     be the case for a REP MOVSW CS:[BX]
  377.                     Note that this also implies that
  378.                     REPZ, REPNZ are affected in SCASW
  379.                     for instance.
  380.  
  381.                                                         
  382.